CodeBuildを使って依存関係のあるコマンドの順序制御と並列化をやってみた
CX事業本部、MAD事業部の小倉@大阪オフィスです。
CodeBuildを使って複数のコマンドを直列実行させていたのですが、
依存関係の無いコマンドはできるだけ並列に実行させたくなったので、方法を調べてみました。
モチベーション
以下の様なコマンド(taskX)をできるだけ並列に実行し、実行時間を短くしたいと思います。
前提条件
- 図のtask1〜task9は全て異なるコマンド
- 矢印でつながっている各taskは、先行するtaskが全て完了した場合のみ実行可能
- (テスト実行の為sleepコマンドで代用)
戦略
CodeBuildのBatchビルド機能のうち、build-graph
を使用します。
このBatchビルド、基本はCodeBuildプロジェクトで指定したbuildspecのビルドコマンドを、各ビルドタスクで実行するのですが、
実は各ビルドタスクにbuildspec
を指定して、それぞれ異なる処理を指示することが出来るのです!!(見落としていました)
(以下はCodeBuildのドキュメントより引用)
buildspec Optional. The path and file name of the buildspec file to use for this task. If this parameter is not specified, the current buildspec file is used.
やってみる
上記の仕様をふまえて、以下の様な方法を考えてみました。
task_group_X
の単位にbuildspec
ファイルを作成してまとめ、
メインとなるbuildspec
でbuild-graph
を使用して実行順序を制御します。
メインとなるbuildspec
(CodeBuildプロジェクトにて指定)
version: 0.2 batch: build-graph: - identifier: task_group_a buildspec: task_group_a.yml - identifier: task_group_b buildspec: task_group_b.yml - identifier: task_group_c buildspec: task_group_c.yml depend-on: - task_group_a - task_group_b - identifier: task_group_d buildspec: task_group_d.yml depend-on: - task_group_c - identifier: task_group_e buildspec: task_group_e.yml depend-on: - task_group_c phases: build: commands: # ここは今回よびだされない想定 - echo Default Start on `$(date)` - sleep 60 - echo Default Start on `$(date)`
グループ化されたコマンドを定義するbuildspec
task_group_a.yml
version: 0.2 phases: build: commands: # Task 1 - echo Task 1 Build started on `date` - sleep 100 - echo Task 1 Build stopped on `date` # Task 2 - echo Task 2 Build started on `date` - sleep 200 - echo Task 2 Build stopped on `date`
他グループも同様のイメージでymlファイルを作成しておきます。
準備が出来たら、マネジメントコンソールからバッチビルドを実行してみます。
実行開始後、画面上にも依存関係が表示されています。
CloudWatchLogsに出力された各コマンドのログを確認してみます。
# TaskGroupA 2022-03-08T10:24:21.661+09:00 Task 1 Build started on Tue Mar 8 01:24:17 UTC 2022 2022-03-08T10:25:59.759+09:00 Task 1 Build stopped on Tue Mar 8 01:25:57 UTC 2022 2022-03-08T10:25:59.759+09:00 Task 2 Build started on Tue Mar 8 01:25:57 UTC 2022 2022-03-08T10:29:17.903+09:00 Task 2 Build stopped on Tue Mar 8 01:29:17 UTC 2022 # TaskGroupB 2022-03-08T10:24:50.557+09:00 Task 3 Build started on Tue Mar 8 01:24:46 UTC 2022 2022-03-08T10:26:28.671+09:00 Task 3 Build stopped on Tue Mar 8 01:26:26 UTC 2022 2022-03-08T10:26:28.671+09:00 Task 4 Build started on Tue Mar 8 01:26:26 UTC 2022 2022-03-08T10:29:48.789+09:00 Task 4 Build stopped on Tue Mar 8 01:29:46 UTC 2022 2022-03-08T10:29:48.789+09:00 Task 5 Build started on Tue Mar 8 01:29:46 UTC 2022 2022-03-08T10:34:46.951+09:00 Task 5 Build stopped on Tue Mar 8 01:34:46 UTC 2022 # TaskGroupC 2022-03-08T10:35:12.487+09:00 Task 6 Build started on Tue Mar 8 01:35:08 UTC 2022 2022-03-08T10:36:50.887+09:00 Task 6 Build stopped on Tue Mar 8 01:36:48 UTC 2022 # TaskGroupD 2022-03-08T10:37:52.467+09:00 Task 7 Build started on Tue Mar 8 01:37:48 UTC 2022 2022-03-08T10:39:30.549+09:00 Task 7 Build stopped on Tue Mar 8 01:39:28 UTC 2022 2022-03-08T10:39:30.549+09:00 Task 8 Build started on Tue Mar 8 01:39:28 UTC 2022 2022-03-08T10:44:30.911+09:00 Task 8 Build stopped on Tue Mar 8 01:44:28 UTC 2022 # TaskGroupE 2022-03-08T10:37:52.216+09:00 Task 9 Build started on Tue Mar 8 01:37:48 UTC 2022 2022-03-08T10:41:10.635+09:00 Task 9 Build stopped on Tue Mar 8 01:41:08 UTC 2022
実行時間をガントチャートにしてみました。
想定通りに並列化出来ている様子が確認できました。
まとめ
build-graph
を使うことで、依存関係があるコマンドを順序制御しながら実行することが出来ました。
実行に時間のかかるコマンド(ビルド等)であればある程、並列化の恩恵を大きく受けられそうですね。
尚、build-list
、build-matrix
でも各ビルドタスクにbuildspec
を個別指定することは可能ですので、 興味のある方は試して頂ければと思います。